/*
* Copyright (C) Microsoft. All rights reserved.  
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License.  You may obtain a copy 
* of the License at http://www.apache.org/licenses/LICENSE-2.0  
* 
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
* WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
* MERCHANTABLITY OR NON-INFRINGEMENT. 
*
* See the Apache License, Version 2.0 for specific language governing 
* permissions and limitations under the License.
*
*/
#pragma once

#include "pch.h"
#include <baja/common.hpp>
#include <baja/math.hpp>

#include <journal/app/constants.h>

namespace journal {

namespace b = baja;
namespace m = baja::math;
namespace g = baja::graphics;
namespace bt = baja::transition_tracking;
namespace jss = journal::services::storage;
namespace jsm = journal::services::memory_tracking;

std::recursive_mutex constants::_viewMutex;
std::recursive_mutex constants::_viewDeferredMutex;
std::weak_ptr<isettings_service> constants::_settings;
std::weak_ptr<g::iengine> constants::_graphics;
std::weak_ptr<a::ivar_console> constants::_varConsole;
std::weak_ptr<a::iapp_shell_service> constants::_shellService;
std::weak_ptr<g::irender_service> constants::_renderService;
std::weak_ptr<a::idebug_console> constants::_debugConsole;
std::weak_ptr<iperformance_service> constants::_performanceService;
std::weak_ptr<jss::istorage_service> constants::_storageService;
std::weak_ptr<bt::itransition_tracking_service> constants::_undoRedoService;
std::weak_ptr<a::iui_service> constants::_uiService;
std::weak_ptr<jsa::iautomation_service> constants::_automationService;
std::weak_ptr<jsm::imemory_tracking_service> constants::_memoryTrackingService;

//general
const b::wchar* constants::general::name::renderShadows = L"general\\render shadows";
const b::wchar* constants::general::name::zoomLevel = L"general\\zoom level";
const b::wchar* constants::general::name::stackState = L"general\\stack state";
const b::wchar* constants::general::name::traceToFile = L"trace tags\\trace to file";
const b::wchar* constants::general::name::traceToOutput = L"trace tags\\trace to output";
const b::wchar* constants::general::name::paperType = L"general\\paper type";
const b::wchar* constants::general::name::lastPageNumber = L"general\\last page number";
const b::wchar* constants::general::name::backgroundPackedColor = L"general\\background color";
const b::wchar* constants::general::name::shadowPackedColor = L"general\\shadow color";
const b::wchar* constants::general::name::shutdownDBSessionOnSuspend = L"general\\shutdown db session on suspend";

const b::float32 constants::general::_pageSlotMargin = 1.3f;
const size_t constants::general::_gridLayoutPageCountY = 3;
const size_t constants::general::_grid2LayoutPageCountY = 4;
const m::point2d constants::general::_pageWorldDimensions = m::point2d(6.f, 8.f);
const b::float32 constants::general::_pageWorldGridWidth = 1/5.f;
m::point2d constants::general::_pagePixelDimensions = m::point2d(1200, 1600);
const b::float32 constants::general::_maxPagePixelWidth = 1400;
const m::point2d constants::general::_thumbnailPixelDimensions = m::point2d(300, 400);
const m::point2d constants::general::_pageSlotWorldDimensions = m::point2d(
    constants::general::_pageWorldDimensions.x + constants::general::_pageSlotMargin,
    constants::general::_pageWorldDimensions.y + constants::general::_pageSlotMargin
    );
const m::vector3d constants::general::_lightAngles = m::vector3d(12.f, 20.f, 0.f);
// NOTE: offset doesn't really matter since in reality we are just using a directional light
const m::vector2d constants::general::_lightOffsetXY = m::vector2d(0.f, 0.f);
const m::vector2d constants::general::_lightFocus = m::vector2d(20.f, 20.f);
const b::float32 constants::general::_lightDistance = 5.f;
const g::color constants::general::_directionalLightColor = g::color(1.f, 1.f, 1.f);
const g::color constants::general::_ambientLightColor = g::color(0.6f, 0.6f, 0.6f);
// green:
//const g::packed_color constants::general::_backgroundPackedColor = g::packColor(255, 153, 219, 115);
//const g::packed_color constants::general::_shadowPackedColor = g::packColor(255, 102, 146, 77);
const g::packed_color constants::general::_backgroundPackedColor = g::packColor(255, 170, 170, 170);
const g::packed_color constants::general::_shadowPackedColor = g::packColor(255, 114, 114, 114);
const b::float32 constants::general::_shadowDarkness = 0.67f; // [0..1] percentage of the background color
const g::color constants::general::_coverColor = g::color(1.f, 0.144f, 0.144f, 0.144f);
const b::int32 constants::general::_mipLevels = 8;
const b::float32 constants::general::_cameraDistance = 125.f;
const b::float32 constants::general::_nearZ = 1.f;
const b::float32 constants::general::_farZ = 1000.f;
const b::wchar* constants::general::_runtimeVarGroupName = L"runtime";
const bool constants::general::_useWARP = false;
const bool constants::general::_shutdownDBSessionOnSuspend = false;
// IMPORTANT!! see comments in common::validatePageCacheSize to know how to set this value!
const size_t constants::general::_pageViewCacheCapacity = 128;
const size_t constants::general::_pageModelCacheCapacity = 128;
const size_t constants::general::_pageModelThreadPoolSize = 1;
const size_t constants::general::_lastPageNumber = 0;
b::stopwatch constants::general::_stopwatch = baja::stopwatch();
const b::float32 constants::general::_pageTurnTapRegion = 0.25f;
const b::float32 constants::general::_pageCurlRegion = 0.25f;
const b::float32 constants::general::_pageCurlEndAngle = 90.f;
const b::float32 constants::general::_pageCurlTransparencyStartAngle = 45.f;
const b::float32 constants::general::_maxCurlDistance = 5.0f;
const b::float32 constants::general::_pageTurnDragDistance = 0.05f;
const b::float32 constants::general::_inertialDeceleration = 0.0025f;
const b::float32 constants::general::_floorDistance = 2.5f;
const bool constants::general::_renderShadows = true;
const view::stack_state constants::general::_stackState = view::stack_state::stacked;
const view::layout_id constants::general::_layoutId = view::layout_id::full;
const bool constants::general::_traceToFile = false;
const bool constants::general::_traceToOutput = true;
const view::paper_type constants::general::_paperType = view::paper_type::paper_4;
const b::wchar* constants::general::_sharedPageFileName = L"shared_page.jpg";
const b::wchar* constants::general::_coverFileName = L"res\\journal_cover.png";
const m::point2d constants::general::_backgroundTextureDimensions = m::point2d(256, 256);
const b::float32 constants::general::_tileFileWidth = 200;
const b::wchar* constants::general::_tileFileName = L"austin-tile.jpg";
const b::wchar* constants::general::_attachmentFileName = L"Page %i.jpg";
const b::wchar* constants::general::_applicationName = L"Austin";
std::vector<std::wstring> constants::general::_imageFormats;
const b::uint32 constants::general::_thumbnailSaveInterval = 2000; // 2 seconds

// animations
const b::float32 constants::animations::_startingScale = 0.1f;
const b::float32 constants::animations::_startingDuration = 1500.f;
const m::point2d constants::animations::_startingAcceleration = m::point2d(0.05f, 0.9f);
const b::float32 constants::animations::_pageMoveDuration = 750.f;
const m::point2d constants::animations::_pageMoveAcceleration = m::point2d(0.005f, 0.4f);
const b::float32 constants::animations::_rotationDuration = 600.f;
const b::float32 constants::animations::_pageSelectDuration = 100.f;
const b::float32 constants::animations::_pageDeleteDuration = 2000.f;
const b::float32 constants::animations::_tapCurlDuration = 500.f;
const m::point2d constants::animations::_defaultAcceleration = m::point2d(0.1f, 0.1f);
const b::float32 constants::animations::_quickDuration = 200.f;
const b::float32 constants::animations::_stackExpansionDuration = 750.f;
const m::point2d constants::animations::_stackExpansionAcceleration = m::point2d(0.005f, 0.4f);
const b::float32 constants::animations::_transitionDuration = 750.f;
const m::point2d constants::animations::_transitionAcceleration = m::point2d(0.005f, 0.4f);
const b::float32 constants::animations::_scrollbarVisibilityDuration = 1000.f;

// references
const b::wchar* constants::references::name::showAxes = L"references\\show axes and world floor";
const b::wchar* constants::references::name::showFPS = L"references\\show frames per second";
const b::wchar* constants::references::name::showViewInfo = L"references\\show view info";
const b::wchar* constants::references::name::showTouchPoints = L"references\\show touch points";
const b::wchar* constants::references::name::showKeys = L"references\\show keys";
const b::wchar* constants::references::name::floorTileCount = L"general\\floor tile count";
const b::wchar* constants::references::name::floorTileSize = L"general\\floor tile size";

const b::int32 constants::references::_debugConsoleLineCount = 60;
const b::wchar* constants::references::_fontName = L"Calibri";
const b::int32 constants::references::_fontSize = 18;
const b::int32 constants::references::_fontSizeSmall = 10;
#ifdef BAJA_DEBUG
const bool constants::references::_showAxes = true;
const bool constants::references::_showFPS = true;
const bool constants::references::_showViewInfo = true;
const bool constants::references::_showTouchPoints = false;
const bool constants::references::_showKeys = false;
#else
const bool constants::references::_showAxes = false;
const bool constants::references::_showFPS = false;
const bool constants::references::_showViewInfo = false;
const bool constants::references::_showTouchPoints = false;
const bool constants::references::_showKeys = false;
#endif
const b::int32 constants::references::_floorTileCount = 100;
const b::float32 constants::references::_floorTileSize = 1.f;

// memory tracking settings
const b::wchar* constants::memory_tracking_settings::name::showMonitors = L"memory tracking\\show monitors";
const bool constants::memory_tracking_settings::_showMonitors = false;

// test_automation_settings

const bool constants::test_automation_settings::_pageStressTestEnabled = false;
const bool constants::test_automation_settings::_strokeStressTestEnabled = false;

const b::wchar* constants::test_automation_settings::name::pageStressTestEnabled = L"automation\\tests\\page stress test\\enabled";
const b::wchar* constants::test_automation_settings::name::strokeStressTestEnabled = L"automation\\tests\\stroke stress test\\enabled";

// page_test_automation_settings
const int constants::page_test_automation_settings::_pageCount = 20;
const int constants::page_test_automation_settings::_sourcePhotoCount = 10;
const int constants::page_test_automation_settings::_photoCountPerPage = 5;
const int constants::page_test_automation_settings::_postPhotoPause = 100;
const int constants::page_test_automation_settings::_strokeCountPerPage = 100;
const int constants::page_test_automation_settings::_postPageCreatePause = 900;
const int constants::page_test_automation_settings::_postSymbolPause = 5;
const int constants::page_test_automation_settings::_postIterationPause = 150;
const int constants::page_test_automation_settings::_fontSize = 1;
const int constants::page_test_automation_settings::_fontThickness = 1;

const b::wchar* constants::page_test_automation_settings::name::pageCount = L"automation\\tests\\page stress test\\page count";
const b::wchar* constants::page_test_automation_settings::name::sourcePhotoCount = L"automation\\tests\\page stress test\\source photo count";
const b::wchar* constants::page_test_automation_settings::name::photoCountPerPage = L"automation\\tests\\page stress test\\max photo count per page";
const b::wchar* constants::page_test_automation_settings::name::postPhotoPause = L"automation\\tests\\page stress test\\post photo pause";
const b::wchar* constants::page_test_automation_settings::name::strokeCountPerPage = L"automation\\tests\\page stress test\\stroke count per page";
const b::wchar* constants::page_test_automation_settings::name::postSymbolPause = L"automation\\tests\\page stress test\\post symbol pause";
const b::wchar* constants::page_test_automation_settings::name::postIterationPause = L"automation\\tests\\page stress test\\post iteration pause";
const b::wchar* constants::page_test_automation_settings::name::fontSize = L"automation\\tests\\page stress test\\font size";
const b::wchar* constants::page_test_automation_settings::name::fontThickness = L"automation\\tests\\page stress test\\font thickness";

// stroke_test_automation_settings
const int constants::stroke_test_automation_settings::_strokeCount = 200;
const int constants::stroke_test_automation_settings::_postPageCreatePause = 900;
const int constants::stroke_test_automation_settings::_postSymbolPause = 5;
const int constants::stroke_test_automation_settings::_fontSize = 1;
const int constants::stroke_test_automation_settings::_fontThickness = 1;

const b::wchar* constants::stroke_test_automation_settings::name::strokeCount = L"automation\\tests\\stroke stress test\\stroke count";
const b::wchar* constants::stroke_test_automation_settings::name::postSymbolPause = L"automation\\tests\\stroke stress test\\post symbol pause";
const b::wchar* constants::stroke_test_automation_settings::name::fontSize = L"automation\\tests\\stroke stress test\\font size";
const b::wchar* constants::stroke_test_automation_settings::name::fontThickness = L"automation\\tests\\stroke stress test\\font thickness";

// playback settings
const bool constants::playback_settings::_maxSpeed = false;
const float constants::playback_settings::_speed = 1.0f;
const int constants::playback_settings::_postPageCreatePause = 900;

const b::wchar* constants::playback_settings::name::maxSpeed = L"automation\\playback\\max speed";
const b::wchar* constants::playback_settings::name::speed = L"automation\\playback\\speed ratio";

// performance
const b::wchar* constants::performance::name::useAmp = L"performance\\C++ amp enabled";
const b::wchar* constants::performance::name::showMonitors = L"performance\\show monitors";
const b::wchar* constants::performance::name::reset = L"performance\\reset";

const int constants::performance::_sampleCount = 40;

const bool constants::performance::_useAmp = false;
#ifdef BAJA_DEBUG
const bool constants::performance::_showMonitors = false;
#else
const bool constants::performance::_showMonitors = false;
#endif

// ink
const b::wchar* constants::ink::name::baseWidth = L"ink\\base width";
const b::wchar* constants::ink::name::renderTechnique = L"ink\\rendering technique";
const b::wchar* constants::ink::name::inkColor = L"ink\\ink color";
const b::wchar* constants::ink::name::pointMinimumDistance = L"ink\\minimium stroke point distance";
const b::wchar* constants::ink::name::rebuildCache = L"ink\\rebuild cache";
const b::wchar* constants::ink::name::smooth = L"ink\\smooth";
const b::wchar* constants::ink::name::smoothVectorized = L"ink\\smooth vectorized";
const b::wchar* constants::ink::name::smoothingInterval = L"ink\\smoothing interval";
const b::wchar* constants::ink::name::inkTool = L"ink\\ink tool";
const b::wchar* constants::ink::name::eraserSizeInPixels = L"ink\\eraser size";
const b::wchar* constants::ink::name::touchInputMode = L"ink\\touch input mode";
const b::wchar* constants::ink::name::showTouchInputToggle = L"ink\\show touch input toggle";
const b::wchar* constants::ink::name::debuggingMode = L"ink\\debugging mode";

const b::float32 constants::ink::_baseWidth = 0.02f;
const int constants::ink::_renderTechnique = static_cast<int>(render_technique::normal);
const int constants::ink::_inkColor = static_cast<int>(ink_color::black);
const b::float32 constants::ink::_pointMinimumDistance = 0.00010f;
const b::float32 constants::ink::_pointMinimumPressureDifference = 0.03f;
const bool constants::ink::_smooth = true;
const bool constants::ink::_smoothVectorized = true;
const int constants::ink::_inkTool = static_cast<int>(ink_tool::pen);
const b::uint32 constants::ink::_eraserSizeInPixels = 10;
const b::uint32 constants::ink::_maxVertexCount = 65000;
const b::uint32 constants::ink::_maxMemoryVertexCount = 300000;
const b::uint32 constants::ink::_maxMemoryVertexCountExpansionRatio = 10;
const b::uint32 constants::ink::_slicesForRoundStamp = 24;
const b::float32 constants::ink::_smoothingInterval = 0.05f;
const bool constants::ink::_touchInputMode = false;
const bool constants::ink::_showTouchInputToggle = false;
const bool constants::ink::_debuggingMode = false;

// page curling animation helper
const b::wchar* constants::page_curling::name::curlTheta = L"page curling\\curl theta";
const b::wchar* constants::page_curling::name::curlAy = L"page curling\\curl Ay";
const b::wchar* constants::page_curling::name::curlAngle = L"page curling\\curl angle";
const b::wchar* constants::page_curling::name::curlConicContribution = L"page curling\\curl conic contribution";

const b::float32 constants::page_curling::_curlTheta = 90.f;
const b::float32 constants::page_curling::_curlAy = -10.f;
const b::float32 constants::page_curling::_curlAngle = 0.f;
const b::float32 constants::page_curling::_curlConicContribution = 1.f;

} // namespace journal